import axios from 'axios'
import type { AxiosInstance, InternalAxiosRequestConfig, Method } from 'axios'
import { useUserStore } from '@/stores'
import { showFailToast } from 'vant'
// import { useRouter } from 'vue-router'
import router from '@/router'
// 创建 axios 实例的基准地址和超时时间
export const baseURL = 'https://consult-api.itheima.net'
const instance: AxiosInstance = axios.create({
  baseURL: 'https://consult-api.itheima.net',
  timeout: 20000
})
// const router = useRouter()
// 使用useRouter（）获取的router实例 和直接将router模块导入获取的router实例 全等
// 但是useRouter() 只能在setup中使用 。vue文件中使用
// 直接引入的方式没有任何限制

// const class router {
//   say() {}
//   sayHello() {}
// }
// router 调用路由上的成员方法使用router
// route 调用路由上的属性配置的时候使用route route是router的子集 相当于 router.currentRoute || router.currentRoute.value

// 配置请求拦截 添加在实例上的
// 在请求头中添加token
// 1、获取token
// 2、判断 token 和hearders是否存在
// 3、如果存在 在header上添加token
instance.interceptors.request.use(
  function (config: InternalAxiosRequestConfig) {
    const userStore = useUserStore()
    if (userStore.userinfo?.token && config.headers) {
      config.headers.Authorization = `Bearer ${userStore.userinfo?.token}`
    }
    return config
  },
  function (error) {
    return Promise.reject(error)
  }
)

// 配置响应拦截 添加在实例上的
instance.interceptors.response.use(
  function (response) {
    console.log(response.data)
    // 处理接口状态码为200 但是接口返回失败的情况
    // 1、在code字段上 如果不是10000统一都是失败
    // 2、如果返回失败
    //   提示用户（使用接口返回值中message）
    //   手动的将promise的状态 变成reject
    const { message, code } = response.data
    if (code !== 10000) {
      showFailToast(message)
      return Promise.reject(response.data)
    }
    // 实现数据的剥离
    return response.data
  },
  function (error) {
    console.log(error)
    const store = useUserStore()
    // const router = useRouter()
    if (error.response.status === 401) {
      // token失效
      // 清除用户信息
      store.clearUserInfo()
      // 跳转登录页
      router.push('/login')
    }
    showFailToast(error.response.data.message)
    // 404
    // 其他请求失败的情况
    return Promise.reject(error)
  }
)

type Data<T> = {
  code: number
  message: string
  data: T
}
const request = <T>(
  url: string,
  // 从axios中引入Method类型（字面量类型配合联合类型）来定义method参数
  // 通过 = 'GET'赋一个初始值 如果请求方法也是get 可以省略不写
  method: Method = 'GET',
  submitData?: object
) => {
  return instance.request<T, Data<T>>({
    url,
    // 'post' 'POST'
    method,
    // 在对象属性中如果key 或者value是一个变量的时候可以通过 []
    // let obj = {
    //   a: 1,
    //   b: 2,
    //   c: 3
    // }
    // obj.a
    // obj['a']
    [method.toLowerCase() === 'get' ? 'params' : 'data']: submitData
  })
}

// 导出 axios 实例
export default request
